package com.advertisementsystem.Controller;

import com.advertisementsystem.Dto.LoginUser;
import com.advertisementsystem.Dto.RegisterDTO;
import com.advertisementsystem.Dto.UserDTO;
import com.advertisementsystem.Dto.UserUpdateDTO;
import com.advertisementsystem.Enum.RoleTypeEnum;
import com.advertisementsystem.Mapper.RoleMapper;
import com.advertisementsystem.Mapper.UserRoleMapper;
import com.advertisementsystem.Servie.UserService;
import com.advertisementsystem.entity.Role;
import com.advertisementsystem.entity.UserRole;
import com.advertisementsystem.Exception.ResponseResult;
import com.advertisementsystem.utils.JwtUtils;
import com.advertisementsystem.utils.RedisCache;
import com.advertisementsystem.vo.UserInfoVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @PostMapping("/login")
    public ResponseResult login(@RequestBody UserDTO user){
        // AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        Authentication authentication = authenticationManager.authenticate(authenticationToken);

        // 如果认证没通过，给出对应的提示
        if(Objects.isNull(authentication)){
            throw new RuntimeException("登录失败");
        }

        // 如果认证通过了，使用userid生成一个jwt
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userid = loginUser.getUser().getId().toString();
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId,loginUser.getUser().getId());
        List<UserRole> roles = userRoleMapper.selectList(queryWrapper);
        LambdaQueryWrapper<Role> roleQueryWrapper = new LambdaQueryWrapper<>();
        roleQueryWrapper.in(Role::getId,roles);
        List<Role> role = roleMapper.selectList(roleQueryWrapper);
        List<String> code = role.stream().map(Role::getCode).toList();
        RoleTypeEnum roleTypeEnum = RoleTypeEnum.getHighestRole(code);
        String userType = roleTypeEnum.getName();
        String jwt = JwtUtils.generateToken(userid,userType);

        // 把完整的用户信息存入redis，userid作为key
        redisCache.setCacheObject("login:"+userid, loginUser,60, TimeUnit.MINUTES);

        // 把token响应给前端
        HashMap<String,String> map = new HashMap<>();
        map.put("token",jwt);
        return new ResponseResult(200,"登录成功",map);
    }


    @PostMapping("/register")
    public ResponseResult<?> register(@RequestBody RegisterDTO registerDTO) {
        return userService.register(registerDTO);
    }


    @PutMapping("/info")
    public ResponseResult<?> updateUserInfo(@RequestBody UserUpdateDTO userUpdateDTO) {
        return userService.updateUserInfo(userUpdateDTO);
    }

    @GetMapping("/info")
    public ResponseResult<UserInfoVO> getUserInfo() {
        return userService.getUserInfo();
    }
}